#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/10/26 14:19
# @Author  : HYCX-AI-LAB Liang jinhao

"""
MQ信息的接收和解析
"""

from utils.MQ.MQ_class import MQ

from utils.epai_thread import start_thread, raise_from_thread
from utils.detection_3d.calculator import Calculator
from utils.detection_3d.detect_tin_beads import DetectTinBeads
from utils.detection_3d.detect_appearance import DetectAppearance
from utils.camera.keyence_camera import Keyence_Camera
from utils.AI_2d.preprocessing.v2.preprocessing import Preprocessing
from utils.AI_2d.inference.inference import TestManager
import threading
import time
import json
from numpy.compat import unicode
from utils.visualization.npy2pcd import NpyConvert

TASK_MAP = {
    '30': "3d_volume",
    '31': "step_modify",
    '40': "tin_beads_detect",
    '50': "PIN_appearance_detect",
    '60': "NPY CONVERT TO PCD",
    '101': "Camera No. Change",
    '102': "Camera Data Get",
    '110': "AI Preprocessing Detection",
    '115': "AI Inference Detection",
    '116': "AI Preprocessing & AI Inference Detection"
}

# preprocessing_map={
#     "task_id": "666",
#     "task_type": "110",
#     "npy": "/home/hycx/PONINT_ALGORITHM_DATA_TEST/2022-06-28/3505277134ML085B085301110012200465_side_2022-06-28-09-05-21.npy",
#     "targetFolder": "/home/hycx/PONINT_ALGORITHM_DATA_TEST/output"
# }

# inference_map = {
#     "task_id": "666",
#     "task_type": "115",
#     "img_path": "/home/hycx/PONINT_ALGORITHM_DATA_TEST/output/3505277134ML085B085301110012200465_up_2022-06-28-09-04-52_meta_channelsBlend.png"
# }

# preprocessing_and_inference_map = {
#     "task_id": "666",
#     "task_type": "116",
#     "npy": "/home/hycx/PONINT_ALGORITHM_DATA_TEST/2022-06-28/3505277134ML085B085301110012200618_up_2022-06-28-08-21-28.npy",
#     "targetFolder": "/home/hycx/PONINT_ALGORITHM_DATA_TEST/output"
# }

# {
#     "task_id": "666",
#     "task_type": "116",
#     "npy": "/home/hycx/PONINT_ALGORITHM_DATA_TEST/2022-06-28/3505277134ML085B085301110012200618_up_2022-06-28-08-21-28.npy",
#     "targetFolder": "预处理结果目录",
#     "detection_target": "检测结果目录"
# }


# {
#     "task_id": "666",
#     "task_type": "60",
#     "npy": "npy文件路径",
#     "target_folder": "保存pcd文件的路径"
# }

list_thead = []
time_sleep = 3
color_map = [
    {
        "name": "ok", "color": "green"
    },
    {
        "name": "nok", "color": "red"
    }
]
pth_file = "./utils/AI_2d/inference/pointCloudLatest.pth"
cfg_file = "./utils/AI_2d/inference/pointCloudCfg.py"


def send_heart(MQ_send, connection_send, message_send_heart, time_sleep):
    '''

    :param MQ_send: 发送队列的对象
    :param connection_send: 发送的连接
    :param task_id: 任务id
    :param task_type: 任务type
    :param time_sleep: 休眠时间
    :return
    '''
    # send_MQ = MQ(name_que)
    # send_connection = send_MQ.create_MQ(auth_name, auth_pwd, address_dateway, address_port, virtual_host)
    message_send_heart = json.dumps(message_send_heart)
    while True:
        # print(message_send_heart)
        MQ_send.send_heart_Message_MQ(connection_send, message_send_heart)
        # MQ_send.send_Message_MQ(connection_send, '1111111')
        time.sleep(time_sleep)


def python_listen_service_callback(ch, body, _1, _2):
    '''
    action when listen a message
    :param ch: MQ channel
    :param body: body of message
    :param name_que: message queue name
    :param auth_name: message queue's author name
    :param auth_pwd: message queue's author password
    :param address_dateway: address_dateway: message queue's address_dateway
    :param address_port: address_dateway: message queue's address_prot
    :param message: message need to be sent
    :param time_sleep: time of send interval
    :param virtual_host: message queue's virtual_host
    :param durable:
    :return:
    '''
    # print(ch," [x] Received %r" % body,_1,_2)
    str_message = unicode(_2, 'UTF-8')
    message = eval(str_message)
    print("MQ listen message ==>", message)

    # 解析message
    try:
        task_id = message['task_id']
        task_type = message['task_type']
    except KeyError as e:
        print(e)
    else:
        try:
            if task_type == '30':
                point_cloud_file = message['point_cloud_file']
                direction = message['direction']

                calculator = Calculator(MQ_send, connection_send, task_id, task_type, point_cloud_file, direction)
                thread_cal_v_service = start_thread(target=calculator.send_res)
                raise_from_thread(thread_cal_v_service)

            elif task_type == '40':
                png = message['png']
                npy = message['npy']
                tin_beads_detector = DetectTinBeads(MQ_send, connection_send, task_id, task_type, npy, png)
                thread_detector_tin_beads_service = start_thread(target=tin_beads_detector.send_res)
                raise_from_thread(thread_detector_tin_beads_service)

            elif task_type == '50':  # useless
                file = message['file']
                pin_appearance_detector = DetectAppearance(MQ_send, connection_send, task_id, task_type, file)
                thread_detector_pin_appearance_service = start_thread(target=pin_appearance_detector.send_res)
                raise_from_thread(thread_detector_pin_appearance_service)

            elif task_type == '60':
                npy = message['npy']
                target_folder = message['target_folder']
                npy_conver = NpyConvert(MQ_send, connection_send, task_id, npy, target_folder)
                thread_npy_convert = start_thread(target=npy_conver.npy2p_x_f())
                raise_from_thread(thread_npy_convert)

            elif task_type == '101':
                programNo_set = message['programNo_set']
                keyence_camera = Keyence_Camera(MQ_send, connection_send, task_id, task_type,
                                                programNo_set=programNo_set)
                keyence_camera_service = start_thread(target=keyence_camera.change_pro_no)
                raise_from_thread(keyence_camera_service)

            elif task_type == '102':
                dmc = message['dmc']
                direction = message['direction']
                keyence_camera = Keyence_Camera(MQ_send, connection_send, task_id, task_type, dmc=dmc,
                                                direction=direction)
                keyence_camera_service = start_thread(target=keyence_camera.get_camera_data)
                raise_from_thread(keyence_camera_service)

            elif task_type == '110':
                npy = message['npy']
                target_folder = message['targetFolder']
                png = npy[:-4] + "_meta.png"
                pre = Preprocessing(MQ_send, connection_send, task_id, task_type, npy, png, 1, target_folder)
                preprocessing_img_generate = start_thread(target=pre.generate_manager)
                raise_from_thread(preprocessing_img_generate)

            elif task_type == '115':
                img_path = message['img_path']
                if message['detection_target'] is None:
                    testManager.set_args(task_id, task_type, img_path)
                else:
                    testManager.set_args(task_id, task_type, img_path, message['detection_target'])
                test_pin = start_thread(target=testManager.send_result)
                raise_from_thread(test_pin)
                # print("AI Inference Detection")

            elif task_type == '116':
                npy = message['npy']
                target_folder = message['targetFolder']
                png = npy[:-4] + "_meta.png"
                if message['detection_target'] is None:
                    testManager.set_preprocessing(task_id, task_type, npy, png, 1, targetFolder=target_folder)
                else:
                    testManager.set_preprocessing(task_id, task_type, npy, png, 1, targetFolder=target_folder,
                                                  detection_target=message['detection_target'])
                test_pin = start_thread(target=testManager.send_result)
                raise_from_thread(test_pin)

            else:
                print("no such type id")
        except Exception as e:
            print(e)
            msg = {
                "task_id": task_id,
                "task_type": TASK_MAP[task_type],
                'msg': e.args[0]
            }
            print(msg)


def listen_channel(MQ_listen, connection_listen, MQ_send, connection_send, time_sleep):
    '''

    :param name_que: message queue name
    :param auth_name: message queue's author name
    :param auth_pwd: message queue's author password
    :param address_dateway: message queue's address_dateway
    :param address_port: message queue's address_port
    :param message: message need to be sent
    :param time_sleep: time of send interval
    :param virtual_host: message queue's virtual_host
    :param auto_ack:
    :param durable:
    :return:
    '''

    # thead: send python service heart
    # listen_MQ = MQ(name_que)

    message_send_heart = {
        "task_id": -1,
        "task_type": "python_service",
        "status": 1
    }
    # python_service_heart = threading.Thread(target=send_heart,args = (MQ_send, connection_send, message_send_heart, time_sleep))
    # python_service_heart.setDaemon(True)
    # list_thead.append(python_service_heart)
    # python_service_heart.start()

    listen_message = MQ_listen.get_Message_MQ(connection_listen, allback=python_listen_service_callback)


if __name__ == '__main__':
    name_que_listen = 'epai.point.cloud.AIQueue'
    auth_name_listen = "ppai"
    auth_pwd_listen = "ppai"
    # address_dateway_listen = "127.0.0.1"
    address_dateway_listen = "rabbitmq"
    address_port_listen = 5672
    time_sleep_listen = 3
    virtual_host_listen = "/"
    auto_ack_listen = True
    exchange_type = 'fanout'
    durable_listen = True
    MQ_listen = MQ(name_que_listen, auth_name_listen, auth_pwd_listen, address_dateway_listen, address_port_listen,
                   virtual_host_listen, auto_ack_listen, exchange_type, durable_listen)
    connection_listen = MQ_listen.create_MQ()

    name_que_send = 'epai.aiCheck'
    auth_name_send = "ppai"
    auth_pwd_send = "ppai"
    # address_dateway_send = "127.0.0.1"
    address_dateway_send = "rabbitmq"
    address_port_send = 5672
    message_send = "11111"
    time_sleep_send = 3
    virtual_host_send = "/"
    auto_ack_send = True
    durable_send = True
    MQ_send = MQ(name_que_send, auth_name_send, auth_pwd_send, address_dateway_send, address_port_send,
                 virtual_host_send,
                 auto_ack_send, exchange_type, durable_send)
    connection_send = MQ_send.create_MQ()

    testManager = TestManager(MQ_send, connection_send, color_map=color_map, pth_file=pth_file, cfg_file=cfg_file)
    listen_channel(MQ_listen, connection_listen, MQ_send, connection_send, time_sleep_send)
